<!--
 * @Author: chen qi
 * @Date: 2022-07-12 00:29:37
 * @LastEditors: chen qi
 * @LastEditTime: 2022-07-14 00:49:30
 * @Description:
-->
<template>
  <div
    :ref="`map2dChart${id}`"
    class="map2d-chart"
  ></div>
</template>

<script>
import commonMixin from '@/utils/mixin'
export default {
  name: 'map2dChart',
  mixins: [commonMixin],
  props: {
    id: {
      type: [Number, String],
      default: 1
    },
    data: {
      type: Array,
      default: () => {
        return []
      }
    }
  },
  data() {
    return {
      // 北京,天津,上海,重庆,澳门,香港
      crowns: [110000, 120000, 310000, 500000, 820000, 810000],
      timeFn: null,
      resDebounce: null, // 防抖
      chart: null, // chart实例,
      // 各省份的数据
      allData: []
    }
  },
  mounted() {
    this.$nextTick(() => {
      this.chart = this.$echarts.init(this.$refs[`map2dChart${this.id}`])
      this.resDebounce = this.debounce(this.chart.resize, 300)
      window.addEventListener('resize', this.resDebounce)
      this.loadMap('100000', 'china')
      this.chart.on('click', (params) => {
      // 点击title
        if (params.componentType === 'title') {
          alert(11)
        } else if (params.componentType === 'series') {
          clearTimeout(this.timeFn)
          this.timeFn = setTimeout(() => {
            const { data } = params
            this.loadMap(data.adcode, data.name, data.level)
          }, 250)
        }
      })
      this.chart.on('dblclick', (params) => {
        console.log(params)
        const { data } = params
        clearTimeout(this.timeFn)
        let prelevel
        let adcode
        console.log(data.adcode)
        if (data.level === 'province' && data.adcode !== 710000) return
        if (data.level === 'city' || data.adcode === 710000) {
          prelevel = ''
          adcode = data.acroutes[0]
        } else if (data.level === 'district') {
        // 是否在直辖市
          if (this.isInCrowns(data.acroutes, this.crowns)) {
            if (this.allData.length === 1) {
              prelevel = 'city'
              adcode = data.acroutes[1]
            } else {
              prelevel = ''
              adcode = data.acroutes[0]
            }
          } else {
            prelevel = 'province'
            if (this.allData.length === 1) {
              adcode = data.acroutes[2]
            } else {
              adcode = data.acroutes[1]
            }
          }
        }
        this.loadMap(adcode, '', prelevel)
      })
    })
  },
  methods: {
    // 判断是否在直辖市内
    isInCrowns(acroutes, crowns) {
      for (let index = 0; index < acroutes.length; index++) {
        const element = acroutes[index]
        if (crowns.includes(element)) return true
      }
      return false
    },
    // 获取对象
    getOption(options = {}) {
      const name = options.name || ''
      const scatters = this.allData.map(item => { return { name: item.name, value: item.center, num: item.value } }).sort((a, b) => a.num - b.num).slice(0, 4)// 地理位置数据
      const effectScatters = this.allData.map(item => { return { name: item.name, value: item.center, num: item.value } }).sort((a, b) => b.num - a.num).slice(0, 4) // 地理位置数据,
      const lines = this.getLines(this.allData, 5)
      const graphs = this.getGraphs()
      const option = {
        title: [
          {
            text: '图一',
            show: true,
            textStyle: {},
            padding: 0,
            top: 10,
            left: 5,
            triggerEvent: true // 是否触发事件
          },
          {
            text: '图二',
            show: true,
            textStyle: {},
            padding: 0,
            top: 10,
            left: 100,
            triggerEvent: true // 是否触发事件
          }
        ],
        // 提示
        tooltip: {
          trigger: 'item', // 触发
          backgroundColor: 'transparent',
          borderColor: 'transparent',
          extraCssText: 'z-index:100;color:#fff;',
          confine: true, // 是否将 tooltip 框限制在图表的区域内
          formatter: function(params, ticket, callback) {
            // 根据业务自己拓展要显示的内容
            var res = ''
            var name = params.name
            var count = params.value ? params.value : 0
            res = `<div style="box-shadow: 0 0 10px #3BD9D9; padding: 10px; position: absolute; top: 0; left:0;  border-radius: 4px; border: 1px solid #04b9ff; background: linear-gradient(to bottom,  #51bfd4 0%,rgba(35,90,178,.8) 100%);">
                             <div style='color:#F4BD59; font-size: 14px;'>${name}</div>
                             <div style="display: flex; align-items: center;padding-top: 6px;">
                              <div style="height: 6px; width: 6px; border-radius: 50%; background:#F4BD59; margin-right: 10px;"></div> <span style='color:#fff;font-size: 12px;margin-right: 20px;'>tooltip</span><span style="font-size: 12px;font-family: 'PangMenZhengDao'">${count}</span>
                             </div>
                          </div>`
            return res
          }
        },
        // 在地图中对特定的区域配置样式。
        regions: [{
          name: '广东省',
          itemStyle: {
            areaColor: 'red',
            color: 'red'
          },
          height: 10
        }],
        // 是视觉映射组件，用于进行『视觉编码』，也就是将数据映射到视觉元素（视觉通道）热力图
        visualMap: {
          type: 'continuous', // continuous 连续性
          calculable: false,
          text: ['高', '低'],
          showLabel: true,
          left: '50',
          min: 0,
          max: 100,
          seriesIndex: [0], // 作用图层
          inRange: {
            color: ['#edfbfb', '#b7d6f3', '#40a9ed', '#3598c1', '#215096']
          },
          splitNumber: 5
        },
        // 地理
        geo3D: {
          map: name,
          roam: false,
          itemStyle: {

            // areaColor: 'rgb(5,101,123)',
            opacity: 1,
            borderWidth: 0.8,
            borderColor: 'rgb(62,215,213)',
            areaColor: 'red'
          },
          label: {
            show: true,
            textStyle: {
              color: '#fff', // 地图初始化区域字体颜色
              fontSize: 14,
              opacity: 0.9,
              backgroundColor: 'rgba(0,0,0,0)'
              // backgroundColor: 'rgba(53,171,199,0)'
            }
          },
          emphasis: { // 当鼠标放上去  地区区域是否显示名称
            label: {
              show: true,

              textStyle: {
                color: 'black',
                fontSize: 3,
                backgroundColor: 'rgba(0,0,0,0)'
              }
            },
            itemStyle: {

              areaColor: 'red',
              color: '#fd9c5a'
            }
          },
          light: { // 光照阴影
            main: {
              // color: '#3ae582', //光照颜色
              color: '#fff', // 光照颜色
              intensity: 1, // 光照强度
              // shadowQuality: 'high', //阴影亮度
              shadow: false, // 是否显示阴影
              alpha: 45,
              beta: 180

            },
            ambient: {
              intensity: 0.3
            }
          },
          viewControl: {
            // // projection: 'orthographic',
            // // 取消鼠标旋转，移动，缩放
            // rotateSensitivity: 0,
            // panSensitivity: 0,
            // zoomSensitivity: 0,
            // // panMouseButton: 'left',
            // // rotateMouseButton: 'right',
            // distance: 93,
            // alpha: 50,
            // beta: 10,
            // center: [0, 0, 0]
          }
        },
        // geo: {
        //   show: true,
        //   map: name,
        //   roam: false, // 鼠标滚动
        //   zoom: 1, // 缩放
        //   // 以某个地理坐标为中心
        //   // center: [112.982279, 28.19409],
        //   label: {
        //     show: false,
        //     color: '#FFFFFF'
        //   },
        //   emphasis: {
        //     label: {
        //       show: true,
        //       color: '#ffffff' // 选中文字颜色
        //     },
        //     itemStyle: {
        //       areaColor: '#2B91B7' // 高亮区域颜色
        //       // opacity:'0.5'
        //     }
        //   },
        //   /** 隐藏南海诸岛右下角小地图 */
        //   regions: [
        //     {
        //       name: '南海诸岛',
        //       /** 隐藏地图，透明度为 0 时不绘制该图形 */
        //       itemStyle: { opacity: 0 },
        //       // 隐藏文字
        //       label: { show: false }
        //     }
        //   ],
        //   itemStyle: {
        //     borderColor: 'rgba(17, 235, 248, 1)',
        //     borderWidth: 1,
        //     areaColor: {
        //       type: 'radial',
        //       x: 0.5,
        //       y: 0.5,
        //       r: 0.8,
        //       colorStops: [{
        //         offset: 0,
        //         color: 'rgba(147, 25, 28, 0)' // 0% 处的颜色
        //       }, {
        //         offset: 1,
        //         color: 'rgba(147, 235, 248, .2)' // 100% 处的颜色
        //       }],
        //       globalCoord: false // 缺省为 false
        //     },
        //     shadowColor: 'rgba(18, 27, 28, 1)',
        //     shadowOffsetX: -2,
        //     shadowOffsetY: 2,
        //     shadowBlur: 10
        //   }
        // },
        // 当前视角的中心点。
        // center: [80, 30],
        series: [
          // 地图
          // {
          //   name: 'MAP',
          //   type: 'map3D',
          //   map: name,
          //   coordinateSystem: 'geo3D',
          //   geoIndex: 0,
          //   // 地面可以让整个组件有个“摆放”的地方，从而使整个场景看起来更真实，更有模型感。
          //   groundPlane: {
          //     // 是否显示地面。[ default: false ]
          //     show: false,
          //     // 地面颜色。[ default: '#aaa' ]
          //     color: '#aaa'
          //   },
          //   scaleLimit: {
          //     // 滚轮缩放的极限控制
          //     min: 1,
          //     max: 2
          //   },
          //   selectedMode: false, // 是否允许选中多个区域
          //   roam: false, // 是否开启鼠标缩放和平移漫游。默认不开启。如果只想要开启缩放或者平移，可以设置成 'scale' 或者 'move'。设置成 true 为都开启
          //   // 地区地名显示
          //   label: {
          //     show: false,
          //     color: '#000'
          //   },
          //   // 地区样式 鼠标滑过
          //   itemStyle: {
          //     label: {
          //       show: true,
          //       color: '#fff'
          //     },
          //     color: '#fff',
          //     borderColor: '#32CBE0',
          //     borderWidth: 1.5,
          //     areaColor: {
          //       type: 'linear-gradient',
          //       x: 0,
          //       y: 1000,
          //       x2: 0,
          //       y2: 0,
          //       colorStops: [
          //         {
          //           offset: 0.5,
          //           color: '#0D59C1' // 0% 处的颜色
          //         },
          //         {
          //           offset: 1,
          //           color: '#53C9C7' // 100% 处的颜色
          //         }
          //       ],
          //       global: true // 缺省为 false
          //     },
          //     emphasis: {
          //       label: {
          //         show: true,
          //         color: '#fff'
          //       },
          //       borderWidth: 3,
          //       borderColor: 'rgba(255, 230, 175,0.8)',
          //       shadowColor: 'rgba(255, 230, 175,0.5)',
          //       shadowBlur: 30,
          //       textStyle: {
          //         color: 'red',
          //         fontSize: 12,
          //         backgroundColor: 'transparent'
          //       },
          //       areaColor: new this.$echarts.graphic.LinearGradient(
          //         0,
          //         0,
          //         0,
          //         1,
          //         [
          //           {
          //             offset: 0,
          //             color: '#1cfbfe'
          //           },
          //           {
          //             offset: 1,
          //             color: '#3348e7'
          //           }
          //         ],
          //         false
          //       )
          //     }
          //   },
          //   // 选中的状态
          //   select: {
          //     label: {
          //       show: true
          //     },
          //     itemStyle: {
          //       areaColor: '#0b59a3'
          //     }
          //   },
          //   // 地理数据
          //   data: this.allData
          // },
          // 气泡
          // {
          //   name: 'scatter',
          //   type: 'scatter',
          //   coordinateSystem: 'geo',
          //   symbol: 'pin',
          //   symbolSize: [40, 40],
          //   // 数据内容
          //   label: {
          //     show: true,
          //     // backgroundColor: 'blue',
          //     textStyle: {
          //       color: '#fff',
          //       fontSize: 10
          //     },
          //     formatter(data) {
          //       return data.data.num
          //     }
          //   },
          //   // 外部容器
          //   itemStyle: {
          //     areaColor: 'green',
          //     color: '#5DBD32' // 标志颜色
          //   },
          //   // 鼠标强调
          //   emphasis: {
          //     scale: true,
          //     label: {
          //       // backgroundColor: 'red',
          //       color: '#fff'
          //     }
          //   },
          //   data: scatters,
          //   showEffectOn: 'render',
          //   rippleEffect: {
          //     brushType: 'stroke'
          //   },
          //   zlevel: 1
          // },
          // // 地图中闪烁的点
          // {
          //   //  name: 'Top 5',
          //   type: 'effectScatter',
          //   coordinateSystem: 'geo',
          //   data: effectScatters,
          //   symbolSize: [10, 5],
          //   showEffectOn: 'render',
          //   rippleEffect: {
          //     scale: 5,
          //     brushType: 'stroke'
          //   },
          //   hoverAnimation: true,
          //   label: {
          //     formatter: () => {
          //       return 1
          //     },
          //     position: 'right',
          //     show: false
          //   },
          //   itemStyle: {
          //     color: '#F46E36',
          //     shadowBlur: 10,
          //     shadowColor: '#F46E36'
          //   },
          //   zlevel: 1
          // },
          // 飞线
          {
            type: 'lines3D',
            coordinateSystem: 'geo3D',
            zlevel: 3,
            // 箭头
            effect: {
              show: true,
              period: 4, // 箭头指向速度，值越小速度越快
              trailLength: 0.1, // 特效尾迹长度[0,1]值越大，尾迹越长重
              symbol: 'circle', // 'arrow', // 箭头图标
              symbolSize: 4, // 图标大小
              color: '#1DE9B6'
            },
            lineStyle: {
              color: '#1DE9B6',
              width: 0.5, // 尾迹线条宽度
              opacity: 0.5, // 尾迹线条透明度
              curveness: 0.3 // 尾迹线条曲直度
            },
            data: lines
          }
          // 节点
          // {
          //   name: 'graph',
          //   type: 'graph',
          //   coordinateSystem: 'geo',
          //   zlevel: 2,
          //   rippleEffect: { brushType: 'stroke' },
          //   label: {

          //     show: false,
          //     opacity: 0,
          //     // position: 'right',
          //     // formatter: '{b}',
          //     color: 'red'
          //     // fontSize: 13

          //   },
          //   itemStyle: {
          //     color: 'green',
          //     opacity: 1
          //   },
          //   emphasis: {
          //     show: false
          //   },
          //   data: graphs
          // }
        ]
      }
      return option
    },
    // 随机几对
    getArrayItems(arr, num) {
      // 新建一个数组,将传入的数组复制过来,用于运算,而不要直接操作传入的数组;
      var temp_array = new Array()
      for (var index in arr) {
        temp_array.push(arr[index])
      }
      // 取出的数值项,保存在此数组
      var return_array = new Array()
      for (var i = 0; i < num; i++) {
        // 判断如果数组还有可以取出的元素,以防下标越界
        if (temp_array.length > 0) {
          // 在数组中产生一个随机索引
          var arrIndex = Math.floor(Math.random() * temp_array.length)
          // 将此随机索引的对应的数组元素值复制出来
          return_array[i] = temp_array[arrIndex]
          // 然后删掉此索引的数组元素,这时候temp_array变为新的数组
          temp_array.splice(arrIndex, 1)
        } else {
          // 数组中数据项取完后,退出循环,比如数组本来只有10项,但要求取出20项.
          break
        }
      }
      return return_array
    },
    /**
     * @description: 飞线
     * @param {*} data
     * @param {*} val
     * @return {*}
     * @author: chen qi
     */

    getLines(data, val) {
      // 随机飞线
      const arrCoords = []
      for (let index = 0; index < val; index++) {
        const temp = this.getArrayItems(data, 2).reduce((pre, cur, i) => {
          if (i === 0) {
            pre.from = cur
            pre.coords = cur.center
          } else {
            pre.to = cur
            pre.coords = [pre.coords, cur.center]
          }
          return pre
        }, {})
        arrCoords.push(temp)
      }
      return arrCoords
    },
    getGraphs() {
      return this.getArrayItems(this.allData.map(item => {
        return {
          name: item.name,
          symbol: 'arrow',
          symbolSize: 8,
          itemStyle: {
            normal: { color: '#FFC809' }
          },
          value: item.center
        }
      }), this.allData.length).slice(0, 5)
    },
    loadMap(mapCode, name = '', level = '') {
      let url
      // 省,市 (除台湾)
      if ((level === 'province' || level === 'city' || level === '') && mapCode !== 710000) {
        url = `https://geo.datav.aliyun.com/areas_v3/bound/${mapCode}_full.json`
      } else {
        url = `https://geo.datav.aliyun.com/areas_v3/bound/${mapCode}.json`
      }
      this.$axios.get(url).then(res => {
        const { data } = res
        this.allData = data.features.map(item => {
          return {
            ...item.properties,
            value: Math.round(Math.random() * 100)
          }
        })
        this.$echarts.registerMap(name, data)
        const option = this.getOption({ name })
        this.$nextTick(() => {
          this.chart.setOption(option)
        })
      }).catch(err => {
        console.log(err)
      })
    }
  },
  destroyed() {
    window.addEventListener('resize', this.resDebounce)
  }
}
</script>

<style lang="less" scoped>
.map2d-chart {
  position: relative;
  width: 100%;
  height: 100%;
}
</style>
